package com.community.shop.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.community.common.result.Result;
import com.community.common.utils.StringUtils;
import com.community.shop.dao.ReadServiceImpl;
import com.community.shop.entity.vo.AddressVo;
import com.community.shop.entity.vo.GoodSkuVo;
import com.community.shop.entity.vo.MessageVo;
import com.community.shop.listener.DemoDataListener;
import com.community.shop.service.ShopService;
import com.community.shop.utils.ListUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/shop")
@Log4j2
public class ShopController {

    @Autowired
    HttpServletRequest request;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    ShopService shopService;

    /**
     * 自动查询地区 转换
     * @return
     */
    @PostConstruct
    public void getInformation(){

        BufferedReader in = null;
        String mess = "";
        List<AddressVo> addressVo = null;
        int count = shopService.findLocalCount();
        // 已添加过
        if(count > 0) {
            return;
        }
        try {
            String urlName = "https://mxnzp.com/api/address/list?app_id=pnjgrriit6wghnlo&app_secret=YXBoenBlWnZmanhLWTRxenNCL1p3Zz09";
            URL url = new URL(urlName);
            URLConnection urlConnection = url.openConnection();
            urlConnection.setRequestProperty("accept","*/*");
            urlConnection.setRequestProperty("connection","Keep-Alive");
            urlConnection.setRequestProperty("user-agent","Mozilla/4.0(compatible;MSIE 6.0;Windows NT 5.1;SV1)");
            urlConnection.connect();
            Map<String, List<String>> headerFields = urlConnection.getHeaderFields();
            in = new BufferedReader(new InputStreamReader(
                    urlConnection.getInputStream()));
            String order;
            while ((order = in.readLine())!=null) {
                mess += order;
            }
            // 反序列化 得到 msg data code
            MessageVo messageVo = JSONObject.parseObject(mess, MessageVo.class);
            // data 反序列化 得到 地区
            addressVo = JSONObject.parseArray(messageVo.getData(), AddressVo.class);
            ArrayList<AddressVo> addressThirdVos = new ArrayList<>();

            // 循环
            addressVo.stream()
                    .forEach((address) -> {
                        // 次id
                        String oid = "0";
                        // 添加一级目录
                        addressThirdVos.add(new AddressVo(address.getCode(),address.getName(),null,oid));
                        // 二级目录
                        address.getPchilds().stream()
                                .forEach((addressSecond) -> {
                                    // 上一级的id
                                    String sid  = address.getCode();
                                    // 添加二级目录
                                    addressThirdVos.add(new AddressVo(addressSecond.getCode(),addressSecond.getName(),null,sid));
                                    // 三级目录
                                    addressSecond.getCchilds().stream()
                                            .forEach((addressThird) -> {
                                                // 上一级目录的id
                                                String tid = addressSecond.getCode();
                                                // 添加三级目录
                                                addressThirdVos.add(new AddressVo(addressThird.getCode(),addressThird.getName(),null,tid));
                                            });
                                });
            });
//            String pid = "0";
//            for (AddressVo vo : addressVo) {
//                addressThirdVos.add(new AddressVo(vo.getCode(),vo.getName(),null,"0"));
//                pid = vo.getCode();
//                for (AddressSecondVo pchild : vo.getPchilds()) {
//                    addressThirdVos.add(new AddressVo(pchild.getCode(),pchild.getName(),null,pid));
//                    pid = pchild.getCode();
//                    for (AddressSecondVo cchild : pchild.getCchilds()) {
//                        addressThirdVos.add(new AddressVo(cchild.getCode(),cchild.getName(),null,pid));
//                    }
//                }
//            }
            // 把集合分成6份
            System.out.println(addressThirdVos.size());
            List<List<AddressVo>> lists = ListUtils.splitList(addressThirdVos, addressThirdVos.size() / 5);

            // 把集合添加进数据库
            for (int i = 0; i < 6; i++) {
                Integer tt = i;
                CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(()->{
                    shopService.addLocalAddress(lists.get(tt));
                    return null;
                });
            }
//            CompletableFuture<String> completableFutureOnce = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(1));
//                return null;
//            });
//            CompletableFuture<String> completableFutureSecond = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(2));
//                return null;
//            });
//            CompletableFuture<String> completableFutureThird = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(3));
//                return null;
//            });
//            CompletableFuture<String> completableFutureFourth = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(4));
//                return null;
//            });
//            CompletableFuture<String> completableFutureFive = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(5));
//                return null;
//            });
//            CompletableFuture<String> completableFutureSix = CompletableFuture.supplyAsync(()->{
//                shopService.addLocalAddress(lists.get(0));
//                return null;
//            });
//            CompletableFuture.allOf(completableFutureOnce,completableFutureSecond,completableFutureThird,completableFutureFourth,completableFutureFive,completableFutureSix).join();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(in!= null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 查找某一地点的下级区域
     * @return
     */
    @PostMapping("/findOneLocal/{name}")
    public Result<AddressVo> findOneLocal(@PathVariable String name){
        log.info("请求路径：【{}】，请求方式：【{}】，请求参数：【{}】",
                request.getRequestURI(),request.getMethod(),name);
        Result<AddressVo> result = null;
        List<AddressVo> list = null;
        // redis中是否有地区缓存
        String local_address = (String) redisTemplate.opsForValue().get("LOCAL_ADDRESS");
        // 没有 -->> 数据库查找
        if(StringUtils.isEmpty(local_address)){
           list = shopService.findLocal();
           redisTemplate.opsForValue().set("LOCAL_ADDRESS",JSONObject.toJSONString(list));
        }
        // 有  -->> 直接反序列化
        if(StringUtils.isNotEmpty(local_address)) {
            list = JSONObject.parseArray(local_address,AddressVo.class);
        }
        // 重新创建一个区域集合
        List<AddressVo> addressVos = new ArrayList<>();
        addressVos.addAll(list);
        List<AddressVo> addressVoLocal = list.stream()
                // 找出查找的一级区域
                .filter(addressVo -> addressVo.getName().equals(name))
                .map((addressVo) -> {
                    // 为一级区域的下级区域赋值
                    addressVo.setOchids(findLocalAddress(addressVos,addressVo));
                    return addressVo;
                }).collect(Collectors.toList());

        result = Result.success(addressVoLocal.get(0));
        log.info("请求路径：【{}】，请求方式：【{}】，响应结果：【{}】",
                request.getRequestURI(),request.getMethod(),result);

        return result;
    }

    /**
     * 递归查找此省的所有下级区域
      */
    public List<AddressVo> findLocalAddress(List<AddressVo> list,AddressVo addressVo) {
        // 此区域的 code
        String code = addressVo.getCode();

        List<AddressVo> collect = list.stream()
                // 查找此区域的下级区域
                .filter(address -> address.getPid().equals(code))
                .map((addressSecond) -> {
                    // 为查找到区域的下级区域赋值
                    addressSecond.setOchids(findLocalAddress(list,addressSecond));
                    // 返回此对象
                    return addressSecond;
                }).collect(Collectors.toList());

        return collect;
    }

    /**
     * 线程实验
     */
    @PostMapping("/tryThread")
    public void tryThread(){
        for (int i = 0; i < 6; i++) {
            Integer r = i;
            CompletableFuture<String> completableFutureSix = CompletableFuture.supplyAsync(()->{
                System.out.println("第："+r+"个");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            });
        }
    }

    /**
     * 求 1-10000的和
     * @return
     */
    @PostMapping("/getAllSum")
    public Result<Integer> getAllSum(){

        // 总和
        Integer sum = 0;
        // 20个线程
        for (int i = 0; i < 20; i++) {
            // 第 N 个线程
            Integer i2 = i;
            CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(()->{
                // 线程所得总和
                Integer count = 0;
                for (int i1 = 1; i1 <= 500; i1++) {
                    count += i2 *500 + i1;
                }
                return count;
            });
            try {
                // 得出每个线程总和
                sum += completableFuture.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println(sum);
        return Result.success(sum);
    }

    @Autowired
    ReadServiceImpl readService;

    /**
     * 读取并存储数据
     * @return
     */
    @PostMapping("/readAndSave")
    public Result<String> readAndSave(@RequestParam("file") MultipartFile multipartFile) throws IOException {

        EasyExcel.read(multipartFile.getInputStream(), GoodSkuVo.class, new DemoDataListener(readService)).sheet().doRead();
        return Result.success("读取成功");
    }

    /**
     * 读取并存入 excel 表格
     * @return
     */
    @PostMapping("/findAndSaveToExcel")
    public Result<String> findAndSaveToExcel(){

        List<GoodSkuVo> list = shopService.findGoodSkuVoList();

        String fileName = "C:\\Users\\猥琐欲为\\Desktop\\"+"商品sku：write" + System.currentTimeMillis() +".xlsx";

        EasyExcel.write(fileName,GoodSkuVo.class).sheet("首").doWrite(list);
        return Result.success("写入成功");
    }
}
